fix: pin GitHub Actions to commit SHAs - #5
Merged
Merged
Conversation
Every `uses:` referenced a mutable tag. A tag can be repointed by whoever controls the upstream repo, and these workflows run with a token that has `contents: write` — enough to push tags and publish releases. A moved tag would execute new code with that token and nothing in the repo would change. Pin to the commits `@v4` and `@v5` resolve to today, so behavior is identical and only the mutability is removed: actions/checkout 11d5960 (v4.4.0) actions/setup-go 40f1582 (v5.6.0) Add a CI step that fails on any `uses:` not pinned to a full 40-character SHA, so this cannot regress. It anchors on `uses:` as a YAML step key rather than matching the token anywhere, since an earlier version flagged its own grep pattern; verified it passes when clean and catches tags, @main, and abbreviated SHAs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VSrrciEDBTuFNMtKocScML
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every
uses:in this repo referenced a mutable tag. I'd recommended SHA pinning in the sibling repo's README but never checked whether these workflows actually did it — they didn't.Why it matters here specifically
release.ymlruns withcontents: write— enough to push tags and publish releases. A tag likeactions/checkout@v4can be repointed by whoever controls that repo, so a moved or compromised tag would execute new code holding that token, with no change to anything in this repository. Tag pinning is a trust-on-every-run assumption; SHA pinning is trust-once.What changed
Pinned to the commits
@v4and@v5resolve to today, so runtime behavior is unchanged and only the mutability is removed — no version bump smuggled in:actions/checkout@v4@11d5960a326750d5838078e36cf38b85af677262(v4.4.0)actions/setup-go@v5@40f1582b2485089dde7abd97c1529aa768e1baff(v5.6.0)All five call sites across
ci.ymlandrelease.yml. Each SHA was verified against upstreamgit ls-remoteto confirm it's a real commit and matches the version in its trailing comment.Note upstream is now at v7 for both. I deliberately did not upgrade — that's a separate change with its own testing burden, and mixing it into a security fix would obscure what actually changed.
Regression guard
A new CI step fails on any
uses:not pinned to a full 40-character SHA.Worth flagging: my first version of this guard had a false positive — it matched the word
uses:inside its own grep pattern and comment, so it failed on a clean tree. It's now anchored touses:as a YAML step key. Tested both directions: passes when clean, and catches@v4,@main, abbreviated SHAs, and@v1.2.3.It also avoids
grep -P, since PCRE support isn't universal across greps.Verification
runblock passesbash -ngofmt,go vet,go test -race ./...cleanNote on the released tag
v1.1.0was published with unpinned actions. Nothing is known to be wrong with it — the released binaries are unaffected, since this only concerns how CI builds them — but the next release will carry the pins.🤖 Generated with Claude Code
https://claude.ai/code/session_01VSrrciEDBTuFNMtKocScML